package com.csair.common.utils;

import android.content.Context;
import android.widget.Toast;

import com.csair.common.AppUtilsConfig;
import com.csair.common.CommonApplication;

import java.lang.reflect.Method;

/***
 *
 * ****************被调用方对外暴露的接口类*******************
 * 接口类的路径:
 * com.csair.mbp.interfaces.XXXXXX
 * 接口类的路径例子:
 * com.csair.mbp.interfaces.bookXXXX
 * com.csair.mbp.interfaces.faceXXXX
 *
 * 暴露的接口类方法可以为以下两种(例子):
 public void testFaceInterface(Context mContext, String jsonString, InterfaceSharp.Callback callbackMethod){
    //如果有需要回调则使用callbackMethod.doThis方法传递一个String参数
    callbackMethod.doThis("testRefStatusContext666");
 }
 public void testFaceInterface(String jsonString, InterfaceSharp.Callback callbackMethod){

 }

 *
 * *****************调用方的使用方法******************
 * @param init 上下文Context，可以为空init()
 * @param call 类名://方法名，不可空
 * @param post jsonString的参数，单层{key1:val1,key2:val2...}
 * @param then 类型为InterfaceSharp.ResponAction，可以为空不加.then(mResponAction)行
 *
 * 以下是kotlin上的调用例子:
 val myOjb = JSONObject()
 try {
    myOjb.put("key1", "val1")
    myOjb.put("key2", "val2")
 } catch (e: Exception) {
    e.printStackTrace()
 }
 val mCallback = InterfaceSharp.Callback {
     Log.e("hereCallback", "hahahah")
 }
 InterfaceSharp.init(this)
                .call("faceXXXX://testFaceInterface")
                .post(myOjb.toString())
                .callback(mCallback)
                .start()
 *
 */
public class InterfaceSharp {
    private final String pathPrefix = "com.csair.mbp.interfaces.";

    private String url;
    private String jsonStr;
    private ResponAction mCallback;

    private String className="";
    private String methodName="";


    private InterfaceSharp(init builder){
        this.className="";
        this.methodName="";
        this.url = builder.urlStr;
        this.jsonStr = builder.jsonStr;
        this.mCallback = builder.mCallback;
        if(null==mCallback){
            mCallback = new ResponAction() {
                @Override
                public void doThis(String jsonString) {
                    //do nothing
                }
            };
        }
        Context  mContext = builder.context;
        Call(mContext);
    }

    private void Call(Context  mContext){
        formatAction(this.url);
        if(!"".equals(className)&&!"".equals(methodName)){
            reflectThisMethod(mContext);
        }
    }

    /***
     * @param urlString com.csair.mbp.reflect.CommonReflectTest://testRefStatus
     * @return
     */
    private void formatAction(String urlString){
        if(!urlString.startsWith(pathPrefix)){
            urlString = pathPrefix+urlString;
        }
        LogUtils.e("ReflectUtil","action:"+urlString);

        try{
            String[] actionSet = urlString.split("://");
            className = actionSet[0];
            methodName = actionSet[1];
        }catch (Exception e){
            LogUtils.printStackTrace(e);
            className = "";
            methodName = "";
        }
        LogUtils.e("ReflectUtil","className:"+className);
        LogUtils.e("ReflectUtil","methodName:"+methodName);
    }


    private void reflectThisMethod(Context  mContext){
        try {
            Class<?> reflectClass = Class.forName(className);
            Object obj = reflectClass.newInstance();
            if(null == mContext){
                Method reflectMethod = reflectClass.getMethod(methodName,
                        String.class, ResponAction.class);
                reflectMethod.invoke(obj, jsonStr,mCallback);
            }else{
                Method reflectMethod = reflectClass.getMethod(methodName,
                        Context.class, String.class, ResponAction.class);
                reflectMethod.invoke(obj, mContext, jsonStr,mCallback);
            }
        } catch (Throwable e) {
            LogUtils.printStackTrace(e);
            if(AppUtilsConfig.getIsDebugMode()){
                Toast.makeText(CommonApplication.getApplication(),className+"://"+methodName+" fail !\n"+e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }


    public static class init {
        private String urlStr;
        private String jsonStr;
        private Context context;
        private ResponAction mCallback;

        public init(Context context){
            this.context = context;
        }
        public init(){

        }

        public init call(String urlStr) {
            this.urlStr = urlStr;
            return this;
        }

        public init post(String jsonStr) {
            this.jsonStr = jsonStr;
            return this;
        }

        public init then(ResponAction mCallback){
            this.mCallback = mCallback;
            return this;
        }

        public InterfaceSharp start() {
            return new InterfaceSharp(this);
        }
    }

    public interface ResponAction {
        void doThis(String jsonString);
    }

}
